package scau.mis4.chanyulin.atm.controller;

import scau.mis4.chanyulin.atm.base.common.CODE;
import scau.mis4.chanyulin.atm.base.system.ConfigConst;
import scau.mis4.chanyulin.atm.base.system.DbService;
import scau.mis4.chanyulin.atm.domain.Account;
import scau.mis4.chanyulin.atm.domain.Card;
import scau.mis4.chanyulin.atm.base.system.Session;
import scau.mis4.chanyulin.atm.domain.Receipt;
import scau.mis4.chanyulin.atm.physical.*;
import java.util.List;

/**
 * Created by chanyulin on 2018/5/24.
 * ATM核心控制器
 */
public class ATM {

    // 硬件
    private CardReader cardReader;
    private Cashier cashier;
    private Logger logger;
    private ReceiptPrinter receiptPrinter;

    // 数据库服务
    private DbService dbService;

    // 是否开机
    private boolean isPowerOn;

    public ATM() {
        this.dbService = new DbService();
    }

    /**
     * 开机
     */
    public void powerOn() {
        logger = new Logger();
        cardReader = new CardReader();
        cashier = new Cashier();
        receiptPrinter = new ReceiptPrinter();
        isPowerOn = true;
    }

    /**
     * 关机
     */
    public int powerOff() {
        int resultCode = ejectCardHandler();
        Session.destroy();
        logger = null;
        cardReader = null;
        cashier = null;
        receiptPrinter = null;
        isPowerOn = false;
        return resultCode;
    }

    /**
     * 插卡
     * @param card
     * @return
     */
    public int insertCardHandler(Card card) {
        if (!isPowerOn) return CODE.ERR_POWER_OFF;
        if (!Session.isEmpty()) return CODE.ERR_SESSION_OCCUPIED;
        if (null == card) return CODE.ERR_NULL_POINTER;
        if (ConfigConst.THIS_BANK_COMPANY != card.getCompany()) return CODE.ERR_UNSUPPORTED_CARD;

        cardReader.insertCard(card);
        Account accountRead = cardReader.readCard();
        if (accountRead != null) {
            // 创建会话记录
            Session.create(accountRead);
            return CODE.MSG_SUCCESS;
        } else {
            cardReader.ejectCard();
            return CODE.MSG_FAILED;
        }

    }

    /**
     * 获取当前会话中的账户
     * @return
     */
    public Account getCurrentAccount() {
        if (!isPowerOn) return null;
        return Session.currentAccount();
    }

    /**
     * 退卡
     * @return
     */
    public int ejectCardHandler() {
        if (!isPowerOn) return CODE.ERR_POWER_OFF;
        if (Session.isEmpty()) return CODE.ERR_SESSION_EMPTY;

        int result = cardReader.ejectCard();
        if (CODE.MSG_SUCCESS == result) {
            // 销毁会话记录
            Session.destroy();
            return CODE.MSG_SUCCESS;
        }

        return CODE.MSG_FAILED;
    }

    /**
     * 取卡
     * @return
     */
    public Card takeCardHandler() {
        return CardReader.takeCard();
    }

    /**
     * 取款
     * @param moneyNeed
     * @return
     */
    public int withdrawMoneyHandler(int moneyNeed) {

        if (!isPowerOn) return CODE.ERR_POWER_OFF;
        if (Session.isEmpty()) return CODE.ERR_SESSION_EMPTY;
        if (moneyNeed <= 0) return CODE.ERR_NUMBER_OUT_OF_RANGE;

        Account account = Session.currentAccount();
        double balance = dbService.getAccountBalance(account.getCardId());
        if (balance < moneyNeed) return CODE.ERR_BALANCE_DEFICIENCY;

        if (CODE.MSG_SUCCESS == dbService.updateBalance(account, 0 - moneyNeed)) {
            cashier.ejectMoney(moneyNeed);
            return CODE.MSG_SUCCESS;
        }

        return CODE.MSG_FAILED;

    }

    /**
     * 取走已出钞票
     * @return
     */
    public int takeMoneyHandler() {
        return Cashier.takeMoney();
    }

    /**
     * 存款
     * @return
     */
    public int saveMoneyHandler() {

        if (!isPowerOn) return CODE.ERR_POWER_OFF;
        if (Session.isEmpty()) return CODE.ERR_SESSION_EMPTY;

        Account account = Session.currentAccount();

        if (CODE.MSG_SUCCESS == dbService.updateBalance(account, cashier.getMoneyCache())) {
            cashier.saveMoney();
            return CODE.MSG_SUCCESS;
        }

        return CODE.MSG_FAILED;

    }

    /**
     * 放入钞票
     * @param moneyPut
     */
    public void putMoneyHandler(int moneyPut) {
        Cashier.putMoney(moneyPut);
    }

    /**
     * 钞票进入暂存区
     */
    public int moveMoneyToCacheHandler() {
        return cashier.moveMoneyToCache();
    }

    /**
     * 钞票退出暂存区
     */
    public int ejectMoneyCacheHandler() {
        return cashier.ejectMoneyCache();
    }

    /**
     * 清点钞票
     * @return
     */
    public int countMoneyHandler() {
        if (!isPowerOn) return CODE.ERR_POWER_OFF;
        if (Session.isEmpty()) return CODE.ERR_SESSION_EMPTY;
        return cashier.countMoneyCache();
    }

    /**
     * 打印凭条
     * @param receipt
     * @return
     */
    public int printReceiptHandler(Receipt receipt) {
        if (!isPowerOn) return CODE.ERR_POWER_OFF;
        if (Session.isEmpty()) return CODE.ERR_SESSION_EMPTY;
        return receiptPrinter.print(receipt);
    }

    /**
     * 取走已打印的凭条
     * @return
     */
    public List<Receipt> takeReceiptsHandler() {
        return ReceiptPrinter.takeAllReceipts();
    }

    /**
     * 记录日志
     * @param text
     */
    public void log(String text) {
        if (!isPowerOn) return;
        logger.log(text);
    }

}
